home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
pcr
/
pcr4_4.lha
/
DIST
/
loading
/
transform_symtab_copy.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-05-30
|
10KB
|
393 lines
/* File: transform_symtab_copy.c - last edit:
* horton Wed Mar 21 12:12:04 1990
*
* Copyright (c) 1989 by Xerox Corporation. All rights reserved.
* Copyright (c) 1990 by Xerox Corporation. All rights reserved. */
/*
* %M% %I% of %G%
* %W%
*/
/* begincopyright
Copyright (c) 1988 Xerox Corporation. All rights reserved.
Use and copying of this software and preparation of derivative works based
upon this software are permitted. Any distribution of this software or
derivative works must comply with all applicable United States export
control laws. This software is made available AS IS, and Xerox Corporation
makes no warranty about the software, its performance or its conformity to
any specification. Any person obtaining a copy of this software is requested
to send their name and post office or electronic mail address to:
PCR Coordinator
Xerox PARC
3333 Coyote Hill Rd.
Palo Alto, CA
endcopyright */
#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <stab.h>
#include <ar.h>
#include <sys/exec.h>
#include <a.out.h>
#undef relocation_info
#define relocation_info reloc_info_sparc
#include <xr/transform.h>
/*
* Transform_symtab reads a short ILsymtab.pidXXX file and produces an a.out file for dbx.
* Each line in the input file is either a common symbol definition or a pointer.
* A common symbol definition is simply appended to the output symbol table.
* A pointer (to an a.out file) will result in the symbol table of the pointed file
* being appended to the output symbol table with the following processing:
* undefined symbols are deleted,
* debugger symbols are deleted if the nodebugger flag for the pointer is true.
* For each symbol table appended to the output file, there is a string table kept
* in memory and written at the end.
*/
struct stringTab { /* structure to represent a string table */
int size; /* size of string table including the count word */
char strings[1];
};
struct stringListElem { /* structure to link string tables together */
struct stringListElem *link;
struct stringTab *ptr;
};
FILE *file; /* output file handle */
struct exec header; /* output file header */
long stringTabLen = 4; /* size of the final string table */
struct stringListElem *stringListHead; /* pointer to head of list of string tables */
struct stringListElem *stringListTail; /* pointer to tail of list of string tables */
struct entry { /* structure to hold info for one symbol table */
/* int nodebugger; */
long address;
long dataAddress;
long bssAddress;
long offset;
char *filename;
FILE *inFile;
struct exec ahdr;
long nsym;
struct nlist *symtab;
struct stringTab *stringtab;
};
/*
* #define free(p) FREE(p)
* #define malloc(c) MALLOC(c)
*/
copy_main()
{
char line[512];
file = stdout;
write_header(); /* position past header, real header written at the end */
while (gets(line, sizeof(line), file) != 0) {
if (line[0] == 'F')
doPointer(line + 2, 0);
else if (line[0] == 'f')
doPointer(line + 2, 1);
else if (line[0] == 'C')
doCommonSymbolDefinition(line + 2);
}
doCommonSymbolDefinition(" 0 _theLastSymbol");
write_stringtab();
write_header(); /* write header info for real */
exit(0);
} /* copy_main */
write_header()
{
double zero;
zero = 0;
header.a_text = sizeof(zero);
rewind(file);
fwrite(&header, sizeof(header), 1, file);
fwrite(&zero, sizeof(zero), 1, file); /* dummy 'text' */
} /* write_header */
doCommonSymbolDefinition(line)
char *line;
{
struct nlist symbol;
char symbolName[512];
int size;
struct stringTab *strp;
char *cp;
symbol.n_type = N_EXT | N_BSS;
symbol.n_other = 0;
symbol.n_desc = 0;
sscanf(line, SYMTAB_PID_COMMON_FORMAT, &symbol.n_value, symbolName);
cp = symbolName;
size = strlen(cp) + 1 + sizeof(int);
strp = (struct stringTab *)malloc(size);
if (strp == 0) {
perror("Copy: doCommonSymbolDefinition: malloc failed");
exit(1);
}
strp->size = size;
strcpy(strp->strings, cp);
symbol.n_un.n_strx = stringTabLen + sizeof(int);
write_sym(&symbol);
appendStringTable(strp);
}
write_sym(p)
struct nlist *p;
{
fwrite(p, sizeof(struct nlist), 1, file);
header.a_syms += sizeof(struct nlist);
}
appendStringTable(strp)
struct stringTab *strp;
{
struct stringListElem *q;
q = (struct stringListElem *)malloc(sizeof(struct stringListElem));
if (q == 0) {
perror("Copy: appendStringTable: malloc failed");
exit(1);
}
q->link = 0;
q->ptr = strp;
if (stringListHead == 0) {
stringListHead = stringListTail = q;
}
else {
stringListTail->link = q;
stringListTail = q;
}
stringTabLen += strp->size;
/* printf("strings - %d\n", strp->size); */
}
doPointer(line, nodebugger)
char *line;
{
struct entry e;
FILE *inFile, *open_file();
struct exec hdr;
int newstringlen, ii;
struct nlist *sp;
char symbolName[512];
char *cp;
struct stringTab *newstringtab;
sscanf(line, SYMTAB_PID_FORMAT, &e.address,
&e.dataAddress, &e.bssAddress, &e.offset, symbolName);
e.filename = symbolName;
e.inFile = open_file(e.filename, &e.ahdr, e.offset);
read_symtab(&e);
fclose(e.inFile);
relocate_symtab(&e);
/*
* make one pass counting strings
*/
for (newstringlen = sizeof(int), ii = 0; ii < e.nsym; ii++) {
sp = e.symtab + ii;
# define UNWANTED ( ( ((sp->n_type & N_TYPE) == N_UNDF) && \
(sp->n_type & N_EXT) \
) || \
(nodebugger && (sp->n_type & N_STAB) \
) \
)
if (UNWANTED) {
continue;
}
cp = (char *)e.stringtab + sp->n_un.n_strx;
newstringlen += strlen(cp) + 1;
}
if (newstringlen < e.stringtab->size) {
/* printf("string table may be reduced from %d to %d\n",
e.stringtab->size, newstringlen); */
newstringtab = (struct stringTab *)malloc(newstringlen);
if (newstringtab == 0) {
perror("Copy: doPointer: malloc failed");
exit(1);
}
newstringtab->size = sizeof(int);
}
else
newstringtab = 0;
/*
* write out symbols, constructing new string table if necessary
*/
for (ii = 0; ii < e.nsym; ii++) {
sp = e.symtab + ii;
if (UNWANTED) {
continue;
}
if (newstringtab) {
cp = (char *)e.stringtab + sp->n_un.n_strx;
strcpy((char *)newstringtab + newstringtab->size, cp);
sp->n_un.n_strx = stringTabLen + newstringtab->size;
newstringtab->size += strlen(cp) + 1;
if (newstringtab->size > newstringlen)
printf("??? error copying strings %d %d\n",
newstringlen, newstringtab->size);
}
else {
sp->n_un.n_strx += stringTabLen;
}
write_sym(sp);
}
free(e.symtab);
if (newstringtab) {
free(e.stringtab);
appendStringTable(newstringtab);
}
else {
appendStringTable(e.stringtab);
}
}
FILE *
open_file(filename, ahdr, offset)
char *filename;
struct exec *ahdr;
{
FILE *returnval;
/* fprintf(stderr, "opening `%s`\n", filename); */
if ((returnval = fopen(filename, "r")) == 0) {
fprintf(stderr, "Cannot open file '%s'.", filename);
exit(1);
}
fseek(returnval, offset, 0);
fread (ahdr, sizeof(struct exec), 1, returnval);
if (N_BADMAG(*ahdr)) {
fprintf(stderr, "magic is %d.\n", ahdr->a_magic);
exit(2);
}
if (header.a_magic == 0) {
header.a_dynamic = ahdr->a_dynamic;
header.a_toolversion = ahdr->a_toolversion;
header.a_machtype = ahdr->a_machtype;
header.a_magic = ahdr->a_magic;
header.a_magic = OMAGIC;
}
return returnval;
} /* open_file */
read_symtab(p)
struct entry *p;
{
long string_len;
p->nsym = p->ahdr.a_syms / sizeof(struct nlist);
/*
* Read in the symbol table
*/
p->symtab = (struct nlist *)malloc(p->ahdr.a_syms);
if (p->symtab == 0) {
perror("Copy: read_symtab: Read symbol table: malloc failed");
exit(1);
}
fseek(p->inFile, p->offset + N_SYMOFF(p->ahdr), 0);
fread (p->symtab, sizeof (struct nlist), p->nsym, p->inFile);
/*
* Read in the string table
*/
fseek(p->inFile, p->offset + N_STROFF(p->ahdr), 0);
fread (&string_len, sizeof(string_len), 1, p->inFile);
if (string_len <= 0) {
fprintf(stderr, "No string table.");
exit(5);
}
p->stringtab = (struct stringTab *)malloc(string_len);
if (p->stringtab == 0) {
perror("Copy: read_symtab: Read string table: malloc failed");
exit(1);
}
fseek(p->inFile, p->offset + N_STROFF(p->ahdr), 0);
fread (p->stringtab, string_len, 1, p->inFile);
/* printf("strings + %d\n", string_len); */
} /* read_symtab */
relocate_symtab(p)
struct entry *p;
{
int ii;
for (ii = 0; ii < p->nsym; ii++) {
switch ((p->symtab[ii].n_type & N_TYPE)) {
case N_TEXT:
p->symtab[ii].n_value += p->address;
break;
case N_DATA:
p->symtab[ii].n_value += p->dataAddress - p->ahdr.a_text;
break;
case N_BSS:
p->symtab[ii].n_value += p->bssAddress - p->ahdr.a_text - p->ahdr.a_data;
break;
}
}
} /* relocate_symtab */
write_stringtab()
{
struct stringListElem *q;
struct stringTab *strp;
/* printf("sum of all string table lengths = %d\n", stringTabLen); */
fwrite(&stringTabLen, sizeof(stringTabLen), 1, file);
for (q = stringListHead; q; q = q->link) {
strp = q->ptr;
/* printf("strings = %d\n", strp->size); */
fwrite(strp, strp->size, 1, file);
}
} /* write_stringtab */
/*
* #undef free
* #undef malloc
*/
FREE(p)
{
free(p);
printf("%06x free\n", p);
}
MALLOC(c)
{
int ret;
ret = malloc(c);
printf("%06x (%06x) malloc\n", ret, c);
return (ret);
}